<?php

/* --------------------------------------------------------------
   CheckModuleSubscriptionStatus.inc.php 2024-08-24
   Gambio GmbH
   http://www.gambio.de
   Copyright (c) 2024 Gambio GmbH
   Released under the GNU General Public License (Version 2)
   [http://www.gnu.org/licenses/gpl-2.0.html]
   --------------------------------------------------------------
*/

use Doctrine\DBAL\Connection;
use Extensions\AdminFeed\Services\ShopInformation\ShopInformationFactory;
use Gambio\Core\Configuration\Services\ConfigurationService;
use Gambio\Core\GXModules\Services\GXModulesComponentsService;

/**
 * Class CheckModuleSubscriptionStatus
 *
 * This extender is used to log admin activity into log data files.
 * The data contains information about name, surname, id ,session id, email, requests url , request parameter and time
 * from current admin.
 */
class CheckModuleSubscriptionStatusController extends AdminHttpViewController
{
    /**
     * @var ConfigurationService|mixed
     */
    private mixed $config;
    /**
     * @var AdminInfoboxControl|mixed
     */
    private mixed $infoBox;
    
    
    public function actionDefault()
    {
        $this->infoBox = MainFactory::create_object('AdminInfoboxControl');
        $this->config  = LegacyDependencyContainer::getInstance()->get(ConfigurationService::class);
        $this->db = LegacyDependencyContainer::getInstance()->get(Connection::class)->createQueryBuilder();
        
        
        $this->languageFiles = LegacyDependencyContainer::getInstance()->get(GXModulesComponentsService::class)->getLanguageFiles();
        $apiURL        = $this->getAPIURL();
        $storeModules  = $this->gambioStoreCurlRequest($apiURL . "/modules", true);
        $subscriptions = $this->gambioStoreCurlRequest($apiURL . "/portal/subscriptions", false);
        $paidModules = $this->gambioStoreCurlRequest($apiURL . "/check/package/payment-needed", true);
        
        
        $noSubscriptionModules = [];
        foreach ($this->getInstalledModules() as $module) {
            foreach ((array)$paidModules['packages'] as $package => $data) {
                
                if(strtoupper($package) === $module)
                {
                    if($data['payment_needed'] === true)
                    {
                        $payDate = $this->getPayDate();
                        $first_date = new DateTime(date('Y-m-d',time()));
                        $second_date = new DateTime($payDate);
                        $difference = $first_date->diff($second_date);
                        if($difference->days <= 0)
                        {
                            $this->uninstallModule($module);
                        }
                        $noSubscriptionModules[$module] = ['title' => $data['title'],'date' => $payDate];
                    }
                }
            }
        }
        $installedModules = [];
        foreach ((array)$storeModules['modules'] as $storeModule) {
            $isInstalled = $this->isModuleInstalled(strtoupper($storeModule['code']));
            if ($isInstalled) {
                $installedModules[] = [
                    "moduleId" => $storeModule['id'],
                    "code"     => $storeModule['code'],
                    "title"   => $storeModule['title'],
                ];
            }
        }
        
        $SubscriptionModules = [];
        if(isset($subscriptions['subscriptionStatusList'])) {
            foreach ((array)$subscriptions['subscriptionStatusList'] as $subscription) {
                foreach ($installedModules as $installedModule) {
                    if ($subscription['moduleId'] === $installedModule['moduleId']) {
                        if ($subscription['subscriptionDetails']['isCancelled'] === true) {
                            if ($subscription['subscriptionDetails']['ends_in_days'] <= 0) {
                                $this->uninstallModule($installedModule['code']);
                                unset($noSubscriptionModules[strtoupper($installedModule['code'])]);
                            } elseif ($subscription['subscriptionDetails']['ends_in_days'] <= 30) {
                                $SubscriptionModules[strtoupper($installedModule['code'])] = [
                                    'title' => $installedModule['title'],
                                    'date'  => $subscription['subscriptionDetails']['ends_at']
                                ];
                            } elseif (isset($noSubscriptionModules[strtoupper($installedModule['code'])])) {
                                unset($noSubscriptionModules[strtoupper($installedModule['code'])]);
                            }
                        }
                    }
                }
            }
        }
        
        $this->infoBox->delete_by_identifier('check-subscription-status',true);
        
        $SubscriptionModules = array_merge($noSubscriptionModules,$SubscriptionModules);
        
        if (!empty($SubscriptionModules)) {
            $this->writeAdminInfoBoxMessage($SubscriptionModules,'check-subscription-status');
        }
        
        return MainFactory::create(JsonHttpControllerResponse::class, ['success' => true]);
    }
    
    
    private function writeAdminInfoBoxMessage($modules,$identifier)
    {
        
        $coo_languages = xtc_get_languages();
        $title = [];
        for ($i = 0; $i < count($coo_languages); $i++) {
            $coo_text_mgr                                   = MainFactory::create_object('LanguageTextManager');
            
            foreach($modules as $module)
            {
                $title[$coo_languages[$i]['id']][] = $module['title'][$coo_languages[$i]['code']].' - '. xtc_date_short($module['date']);
            }
            $t_headline_array[$coo_languages[$i]['id']]     = $coo_text_mgr->get_text('information','module_center',$coo_languages[$i]['id']);
            $t_messages_array[$coo_languages[$i]['id']]     = $coo_text_mgr->get_text('subscription_ended','module_center',$coo_languages[$i]['id'])
                                                              . "<br /><br />"
                                                              . implode('<br>', $title[$coo_languages[$i]['id']]) . "<br><br>"
                                                              . $coo_text_mgr->get_text('goto_module_center','module_center',$coo_languages[$i]['id']);
            $t_button_label_array[$coo_languages[$i]['id']] = $coo_text_mgr->get_text('modules_center','module_center',$coo_languages[$i]['id']);
        }

        $this->infoBox->add_message($t_messages_array, 'info', $t_headline_array, $t_button_label_array,'modules','hideable', 'new', $identifier);
        
    }
    
    private function uninstallModule($moduleName): bool
    {
        $find = $this->config->find("gm_configuration/MODULE_CENTER_" . $moduleName . "_INSTALLED");
        if ($find && $find->value() === "1") {
            $this->config->save("gm_configuration/MODULE_CENTER_" . $moduleName . "_INSTALLED","0");
        }
        
        return false;
    }
    
    function getLanguageFile($moduleCode)
    {
        $files = $this->languageFiles;
        foreach ($files as $file) {
          if(strpos(str_replace('/','',$file->filePath()), $moduleCode) !== false) {
              $section = basename($file->filePath(),'.lang.inc.php');
              $sections[strtolower($moduleCode)] = explode('.', $section);
              
          }
        }
        return $sections;
    }
    
    
    private function getAPIURL()
    {
        return $this->config->find("gm_configuration/GAMBIO_STORE_API_URL")->value();
    }
    
    private function getPayDate()
    {
        $date = $this->db->select('DATE_FORMAT(DATE_ADD(installation_date,INTERVAL 30 day),"%Y-%m-%d") AS payDate')->from('version_history')->where('version = "5.0.0.0"')->executeQuery()->fetchAssociative();
        
        return $date['payDate'];
    }
    
    private function isModuleInstalled($moduleName)
    {
        $find = $this->config->find("gm_configuration/MODULE_CENTER_" . $moduleName . "_INSTALLED");
        if ($find && $find->value() === "1") {
            return true;
        }
        
        return false;
    }
    
    private function getInstalledModules()
    {
        $find = $this->db->select('`key`','`value`')->from('gx_configurations')->where('`key` LIKE "gm_configuration/MODULE_CENTER_%_INSTALLED"');
        $modules = $find->executeQuery()->fetchAllAssociative();
        
        $matches = [];
        $installed = [];
        foreach ($modules as $module)
        {
            preg_match("/MODULE_CENTER_(.*)_INSTALLED/",$module['key'], $matches);
            if($module['value'] === '1')
                $installed[] = $matches[1];
        }

        return $installed;
        
    }
    
    
    private function getCurlRequestBody(): string
    {
        static $body;
        
        if ($body !== null) {
            return $body;
        }
        
        $factory = new ShopInformationFactory();
        
        $service    = $factory->createService();
        $serializer = $factory->createShopInformationSerializer();
        
        $codes = $this->getInstalledModules();
        $body  = json_encode(['shopInformation' => $serializer->serialize($service->getShopInformation()), 'codes' => $codes]);
        
        return $body;
    }
    
    
    private function gambioStoreCurlRequest(string $url, $post)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
        if ($post) {
            curl_setopt($ch, CURLOPT_POST, $post);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $this->getCurlRequestBody());
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json;charset=UTF-8',
            'x-store-token: ' . gm_get_conf('GAMBIO_STORE_TOKEN'),
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        $response    = curl_exec($ch);
        $errorNumber = curl_errno($ch);
        curl_close($ch);
        
        if ($errorNumber !== 0) {
            return false;
        }
        
        return @json_decode($response, true);
    }
    
    
    private function getInstalledModuleCenterModules()
    {
    }
}